package com.quanshi.shopping_user_service.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.quanshi.shopping_common.constant.Constant;
import com.quanshi.shopping_common.constant.RedisKey;
import com.quanshi.shopping_common.entity.ShoppingUser;
import com.quanshi.shopping_common.enums.BusErrorEnum;
import com.quanshi.shopping_common.exception.BusException;
import com.quanshi.shopping_common.service.IShoppingUserService;
import com.quanshi.shopping_user_service.mapper.ShoppingUserMapper;
import com.quanshi.shopping_user_service.util.JwtUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import java.time.Duration;
import java.util.Map;
import java.util.Objects;

@DubboService
public class ShoppingUserServiceImpl implements IShoppingUserService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private ShoppingUserMapper shoppingUserMapper;

    @Override
    public void saveRegisterCheckCode(String phone, String checkCode) {

        ValueOperations<String, String> vos = stringRedisTemplate.opsForValue();

        //如果key存在，说明当前已经发送验证码，提示用户，发送过于频繁
        Boolean hasKey = stringRedisTemplate.hasKey(StrUtil.format(RedisKey.REGISTER_USER_KEY, phone));
        if (Boolean.TRUE.equals(hasKey)) {
            BusException.busException(BusErrorEnum.VERIFY_CODES_EXISTS);
        }

        //设置手机验证码60s过期
        vos.set(StrUtil.format(RedisKey.REGISTER_USER_KEY, phone), checkCode, Duration.ofSeconds(60));
    }

    @Override
    public void registerCheckCode(String phone, String checkCode) {

        //如果key存在，说明当前已经发送验证码，提示用户，发送过于频繁
        Boolean hasKey = stringRedisTemplate.hasKey(StrUtil.format(RedisKey.REGISTER_USER_KEY, phone));
        if (Boolean.FALSE.equals(hasKey)) {
            BusException.busException(BusErrorEnum.VERIFY_CODES_ERROR);
        }

        //获取操作redis
        ValueOperations<String, String> vos = stringRedisTemplate.opsForValue();
        //获取redis的验证码
        String redisValue = vos.get(StrUtil.format(RedisKey.REGISTER_USER_KEY, phone));

        //比较用户输入的和redis是否相等
        if (!checkCode.equals(redisValue)) {
            BusException.busException(BusErrorEnum.VERIFY_CODES_ERROR);
        }

    }

    @Override
    public void register(ShoppingUser shoppingUser) {
        /**
         * 1. 检查账号是否存在
         *  存在：抛出逻辑异常
         *  不存在：注册
         */
        LambdaQueryWrapper<ShoppingUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShoppingUser::getUsername, shoppingUser.getUsername());

        ShoppingUser dbUser = shoppingUserMapper.selectOne(queryWrapper);

        if (Objects.nonNull(dbUser)) {
            BusException.busException(BusErrorEnum.USERNAME_EXISTS_ERROR);
        }


        //设置状态
        shoppingUser.setStatus(Constant.Y);
        //密码加密
        String password = shoppingUser.getPassword();
        shoppingUser.setPassword(SecureUtil.md5(password));
        //保存用户
        shoppingUserMapper.insert(shoppingUser);
    }

    @Override
    public String loginPassword(String username, String password) {

        //根据账号密码条件查询
        LambdaQueryWrapper<ShoppingUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShoppingUser::getUsername,username);
        queryWrapper.eq(ShoppingUser::getPassword,SecureUtil.md5(password));

        ShoppingUser shoppingUser = shoppingUserMapper.selectOne(queryWrapper);
        if(Objects.isNull(shoppingUser)){
            BusException.busException(BusErrorEnum.LOGIN_ERROR);
        }

        //发放令牌
        return JwtUtils.sign(shoppingUser.getId(), shoppingUser.getUsername());
    }

    @Override
    public void saveLoginCheckCode(String phone, String checkCode) {
        //根据手机查询账号是否存在
        LambdaQueryWrapper<ShoppingUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShoppingUser::getPhone, phone);

        Long count = shoppingUserMapper.selectCount(queryWrapper);
        if (count < 0) {
            BusException.busException(BusErrorEnum.PHONE_NO_REGISTER_ERROR);
        }


        ValueOperations<String, String> vos = stringRedisTemplate.opsForValue();

        //如果key存在，说明当前已经发送验证码，提示用户，发送过于频繁
        Boolean hasKey = stringRedisTemplate.hasKey(StrUtil.format(RedisKey.LOGIN_USER_KEY, phone));
        if (Boolean.TRUE.equals(hasKey)) {
            BusException.busException(BusErrorEnum.VERIFY_CODES_EXISTS);
        }
        //设置手机验证码60s过期
        vos.set(StrUtil.format(RedisKey.LOGIN_USER_KEY, phone), checkCode, Duration.ofSeconds(60));

    }

    @Override
    public String loginCheckCode(String phone, String checkCode) {

        /**
         * 1，检查验证码是否正确
         * 2，查询出用户返回用户名
         */
        ValueOperations<String, String> vos = stringRedisTemplate.opsForValue();

        //获取redis验证码
        String redisValue = vos.get(StrUtil.format(RedisKey.LOGIN_USER_KEY, phone));

        if (!checkCode.equals(redisValue)) {
            BusException.busException(BusErrorEnum.VERIFY_CODES_ERROR);
        }

        //根据手机查询账号是否存在
        LambdaQueryWrapper<ShoppingUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShoppingUser::getPhone, phone);

        ShoppingUser shoppingUser = shoppingUserMapper.selectOne(queryWrapper);

        //生成令牌token
        return JwtUtils.sign(shoppingUser.getId(), shoppingUser.getUsername());
    }



    @Override
    public String getName(String token) {
        Map<String, Object> map = JwtUtils.verify(token);
        Object username = map.get("username");
        return (String) username;
    }

    @Override
    public ShoppingUser getLoginUser(Long id) {
        ShoppingUser shoppingUser = shoppingUserMapper.selectById(id);
        return shoppingUser;
    }
}
